package com.daxia.bumall.web.controller.m;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.daxia.bumall.common.MyJSONObject;
import com.daxia.bumall.common.SessionCache;
import com.daxia.bumall.common.SystemConfigType;
import com.daxia.bumall.dto.UserDTO;
import com.daxia.bumall.dto.ValidateCodeDTO;
import com.daxia.bumall.dto.api.MobileApiOutput;
import com.daxia.bumall.dto.api.info.BaseInfoAPIDTO;
import com.daxia.bumall.exception.BizException;
import com.daxia.bumall.model.BaseModel;
import com.daxia.bumall.model.User;
import com.daxia.bumall.security.PasswordEncoder;
import com.daxia.bumall.service.AdService;
import com.daxia.bumall.service.AddressService;
import com.daxia.bumall.service.BizConfigService;
import com.daxia.bumall.service.BrandStyleService;
import com.daxia.bumall.service.BrowseRecordService;
import com.daxia.bumall.service.CityService;
import com.daxia.bumall.service.CommunityHouseTypeService;
import com.daxia.bumall.service.CommunityService;
import com.daxia.bumall.service.CompanyService;
import com.daxia.bumall.service.DecorateNoteClickService;
import com.daxia.bumall.service.DecorateNoteCommentService;
import com.daxia.bumall.service.DecorateNoteDetailService;
import com.daxia.bumall.service.DecorateNoteService;
import com.daxia.bumall.service.DepartmentService;
import com.daxia.bumall.service.DesignerInfoService;
import com.daxia.bumall.service.DesignerService;
import com.daxia.bumall.service.DistrictService;
import com.daxia.bumall.service.FactoryInfoService;
import com.daxia.bumall.service.GzActivityService;
import com.daxia.bumall.service.PayService;
import com.daxia.bumall.service.ProductCategorySpaceService;
import com.daxia.bumall.service.ProductCategoryTagService;
import com.daxia.bumall.service.ProductCollectService;
import com.daxia.bumall.service.ProductService;
import com.daxia.bumall.service.ProfitService;
import com.daxia.bumall.service.ProvinceService;
import com.daxia.bumall.service.SeedService;
import com.daxia.bumall.service.SpaceObjectService;
import com.daxia.bumall.service.SpaceService;
import com.daxia.bumall.service.SystemConfigService;
import com.daxia.bumall.service.TaskService;
import com.daxia.bumall.service.UserDesignDetailService;
import com.daxia.bumall.service.UserDesignService;
import com.daxia.bumall.service.UserHeadImagesService;
import com.daxia.bumall.service.UserService;
import com.daxia.bumall.service.UserTaskRecordService;
import com.daxia.bumall.service.UserTaskService;
import com.daxia.bumall.service.ValidateCodeService;
import com.daxia.bumall.support.Page;
import com.daxia.bumall.util.BeanMapper;
import com.daxia.bumall.util.DevUtils;
import com.daxia.bumall.util.EmailUtils;
import com.daxia.bumall.util.ImageUtils;
import com.daxia.bumall.util.JsonUtils;
import com.daxia.bumall.util.MyWebUtils;
import com.daxia.bumall.util.ValidationUtils;
import com.daxia.bumall.web.controller.BaseController;
import com.google.common.collect.Lists;

/**
 * 为手机提供服务的
 */
public abstract class MBaseController extends BaseController {
    @Autowired
    protected UserDesignDetailService userDesignDetailService;

    @Autowired
    protected UserDesignService userDesignService;

    @Autowired
    protected ProductCategorySpaceService productCategorySpaceService;

    @Autowired
    protected SpaceObjectService spaceObjectService;

    @Autowired
    protected SpaceService spaceService;

    @Autowired
    protected GzActivityService gzActivityService;

    @Autowired
    protected BrowseRecordService browseRecordService;

    @Autowired
    protected ProductCollectService productCollectService;

    @Autowired
    protected BrandStyleService brandStyleService;

    @Autowired
    protected ProfitService profitService;

    @Autowired
    protected DepartmentService departmentService;

    @Autowired
    protected SeedService seedService;

    @Autowired
    protected ProductCategoryTagService productCategoryTagService;

    @Autowired
    protected UserHeadImagesService userHeadImagesService;

    @Autowired
    protected PayService payService;

    @Autowired
    protected CommunityHouseTypeService communityHouseTypeService;

    @Autowired
    protected CommunityService communityService;

    @Autowired
    protected UserTaskRecordService userTaskRecordService;

    @Autowired
    protected UserTaskService userTaskService;

    @Autowired
    protected TaskService taskService;

    @Autowired
    protected DecorateNoteCommentService decorateNoteCommentService;

    @Autowired
    protected DecorateNoteService decorateNoteService;

    @Autowired
    protected DecorateNoteDetailService decorateNoteDetailService;

    @Autowired
    protected CompanyService companyService;

    @Autowired
    protected DesignerInfoService designerInfoService;

    @Autowired
    protected FactoryInfoService factoryInfoService;

    @Autowired
    protected BizConfigService bizConfigService;

	@Autowired
	private SessionCache sessionCache;
	
    @Autowired
    protected AdService adService;

    @Autowired
    protected CityService cityService;

    @Autowired
    protected ProvinceService provinceService;

	@Autowired
	protected ValidateCodeService validateCodeService;
	
    private static Logger logger = Logger.getLogger(MBaseController.class);
    
    @Autowired
    protected AddressService addressService;

    @Autowired
    protected ProductService productService;

    @Autowired
    protected EmailUtils emailUtils;

    @Autowired
    protected UserService userService;
    
    @Autowired
    protected DistrictService districtService;
    
    @Autowired
    protected SystemConfigService systemConfigService;
    
    @Autowired
    protected PasswordEncoder passwordEncoder;
    
    @Autowired
    protected DesignerService designerService;
    
    @Autowired
    protected DecorateNoteClickService decorateNoteClickService;
    
    private String enc = "utf-8";

    protected String toJson(Object obj) {
        MobileApiOutput output = new MobileApiOutput();
        output.setData(obj);
        return JsonUtils.toJson(output);
    }
    
    protected String toJson() {
    	return this.toJson("");
    }

    @SuppressWarnings({ "rawtypes" })
    protected String toApiOutput(List<? extends BaseModel> dtos, Class apiDTO, Class infoAPIDTO) throws Exception {
        return toApiOutput(dtos, apiDTO, infoAPIDTO, null);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    protected String toApiOutput(List<? extends BaseModel> dtos, Class apiDTO, Class infoAPIDTO, Page page) throws Exception {
    	return this.toApiOutput(dtos, apiDTO, infoAPIDTO, page, null);
    }
    
    @SuppressWarnings({ "rawtypes", "unchecked" })
    protected String toApiOutput(List<? extends BaseModel> dtos, Class apiDTO, Class infoAPIDTO, Page page, IAPIConerter conerter) throws Exception {
        List apidtos = Lists.newArrayList();

        for (BaseModel d : dtos) {
        	if (conerter == null) {
             apidtos.add(BeanMapper.map(d, apiDTO));
        	} else {
        		apidtos.add(conerter.fromDTO2APIDTO(d));
        	}
        }

        Class cls = infoAPIDTO;
        Class[] paramTypes = { List.class };
        Constructor con = cls.getConstructor(paramTypes);
        BaseInfoAPIDTO infos = (BaseInfoAPIDTO) con.newInstance(apidtos);

        if (infos != null && page != null) {
            infos.setPageSize(integerToString(page.getPageSize()));
            infos.setPage(integerToString(page.getPage()));
            infos.setTotalPages(integerToString(page.getTotalPages()));
            infos.setTotalRecords(integerToString(page.getTotalRecords()));
        }
        return this.toJson(infos);
    }

    private String integerToString(Integer integer) {
        if (integer == null) {
            return "";
        } else {
            return integer.toString();
        }

    }

    @SuppressWarnings({ "rawtypes" })
    protected String toApiOutput(BaseModel dto, Class apiDTO, Class infoAPIDTO) throws Exception {
        List<BaseModel> list = Lists.newArrayList();
        list.add(dto);
        return toApiOutput(list, apiDTO, infoAPIDTO);
    }

    protected String getCtx(HttpServletRequest request) {
        return request.getSession().getAttribute("ctx").toString();
    }
    
    protected String getCtx() {
        return MyWebUtils.getCurrentRequest().getSession().getAttribute("ctx").toString();
    }

    protected String saveFileAndReturnFileName(HttpServletRequest request, String formInputName) throws IOException {
        try {
            MultipartHttpServletRequest mhs = (MultipartHttpServletRequest) request;
            MultipartFile mf = mhs.getFile(formInputName);
            String fileName = null;
            if (!mf.isEmpty()) {
                fileName = mf.getOriginalFilename();
                fileName = UUID.randomUUID().toString() + fileName.substring(fileName.lastIndexOf("."));
                File file = new File(systemConfigService.get(SystemConfigType.ImagePath) + "/" + fileName);
                if (!file.exists()) {
                    mf.transferTo(file);
                }
            }
            return fileName;
        } catch (Exception e) {
            return null;
        }
    }
    
    protected List<String> saveFilesAndReturnFilesNames(HttpServletRequest request, String name) throws IOException {
        try {
            List<String> fileNames = new ArrayList<String>();
            MultipartHttpServletRequest mhs = (MultipartHttpServletRequest) request;
            //Collection<MultipartFile> mfs = mhs.getFileMap().values();
            List<MultipartFile> mfs = mhs.getFiles(name);
            if (CollectionUtils.isNotEmpty(mfs)) {
                for (MultipartFile mf : mfs) {
                    if (!mf.isEmpty()) {
                        String fileName = ImageUtils.uploadToCDNAndGetUrl(mf.getBytes());
                        fileNames.add(fileName);
                    }
                }
            }
            return fileNames;
        } catch (Exception e) {
            return Lists.newArrayList();
        }
    }
    
    protected void validateCode(String mobile, String validateCode) {
        ValidateCodeDTO oldCode = validateCodeService.findByMobile(mobile);
        if (oldCode == null) {
            throw new BizException("验证码不正确");
        } else {
            if (System.currentTimeMillis() - oldCode.getTime() > (5 * 60 * 1000)) { // 验证码失效了
                throw new BizException("验证码已失效");
            }
            if (!oldCode.getValidateCode().equalsIgnoreCase(validateCode)) {
                throw new BizException("验证码不正确");
            }
        }
        validateCodeService.deleteById(oldCode.getId());
    }
    
    
    protected void assertNotBlank(String value, String msg) {
        ValidationUtils.assertTrue(StringUtils.isNotBlank(value), msg);
    }

    protected void setPageInfo(MyJSONObject jsonObject, Page page) {
        jsonObject.put("page", page.getPage());
        jsonObject.put("pageSize", page.getPageSize());
        jsonObject.put("totalPages", page.getTotalPages());
        jsonObject.put("totalRecords", page.getTotalRecords());
    }
    
    protected void requiredString(String value, String message) {
        if (StringUtils.isBlank(value)) {
            throw new BizException(message);
        }
    }
    
    protected void required(Object value, String message) {
        if (value == null) {
            throw new BizException(message);
        }
    }
    public String appendRedirectUrl(String ctx, String originalUrl, Long promoId, Long userId) throws Exception {
        originalUrl = URLEncoder.encode(originalUrl, enc);
        String url = ctx + "/m/promo/redirect?url=" + originalUrl + "&promoId=" + promoId;
        if (userId != null) {
            url = url + "&userId=" + userId;
        }
        return url;
    }
    
    protected void title(String title) {
        MyWebUtils.getCurrentRequest().setAttribute("title", title);
    }
    
    protected UserDTO getCurrentUserDTO() {
    	if (DevUtils.isLocal()) {
    		return userService.load(1L);
    	}
    	String sessionId = MyWebUtils.getCurrentRequest().getHeader("sessionId");
    	if (StringUtils.isBlank(sessionId)) {
    		return null;
    	}
    	Long userId = sessionCache.getUserId(sessionId);
    	if (userId == null) {
    		return null;
    	}
    	return userService.load(userId);
    }
    
    protected User getCurrentUser() {
    	User user = new User();
    	if (DevUtils.isLocal()) {
    		return userService.load(134L);
    	}
    	String sessionId = MyWebUtils.getCurrentRequest().getHeader("sessionId");
    	logger.info("Get Current User SessionID  :" + sessionId);
    	if (StringUtils.isBlank(sessionId)) {
    		return null;
    	}
    	Long userId = sessionCache.getUserId(sessionId);
    	if (userId == null) {
    		return null;
    	}
    	UserDTO userDTO = userService.load(userId);
    	BeanUtils.copyProperties(userDTO, user);
    	return user;
    }
    
    protected void notNull(Object obj, String msg) {
    	if (obj == null) {
    		throw new RuntimeException(msg);
    	}
    }
}
